#include "CLink/Router/Router.h"
#include "CLink/Router/NotFoundHandler.h"
#include "CLink/Router/ErrorHandler.h"
#include "CLink/error/Error.h"

#include <algorithm>

namespace CLink
{
namespace Router
{

// Router构造函数实现
Router::Router()
{
    _pLogger = nullptr;
    // 设置默认的404处理器
    setNotFoundHandler(std::make_shared<NotFoundHandler>());

    // 设置默认的错误处理器
    setErrorHandler(std::make_shared<ErrorHandler>());
}

// RouteGroup实现
RouteGroup::RouteGroup(const std::string &prefix)
    : m_prefix(prefix)
{
}

RouteGroup &RouteGroup::addHandler(std::shared_ptr<IRouteHandler> handler)
{
    // 使用二分查找找到合适的位置插入，保持按优先级从高到低排序
    auto it = std::lower_bound(m_handlers.begin(), m_handlers.end(), handler,
                                [](const std::shared_ptr<IRouteHandler> &a, const std::shared_ptr<IRouteHandler> &b)
                                {
                                    return a->getPriority() > b->getPriority();
                                });
    m_handlers.insert(it, handler);
    return *this;
}

RouteGroup &RouteGroup::addMiddleware(MiddlewareHandler middleware)
{
    m_middlewares.push_back(middleware);
    return *this;
}

const std::string &RouteGroup::getPrefix() const
{
    return m_prefix;
}

const std::vector<std::shared_ptr<IRouteHandler>> &RouteGroup::getHandlers() const
{
    return m_handlers;
}

const std::vector<MiddlewareHandler> &RouteGroup::getMiddlewares() const
{
    return m_middlewares;
}

void Router::setDBManager(CLink::Db::DatabaseManager::Ptr db)
{
    _dbManager = db;
}

void Router::setLogger(Poco::Logger& logger)
{
    _pLogger = &logger;
}

Router &Router::addHandler(std::shared_ptr<IRouteHandler> handler)
{
    if (handler)
    {
        m_handlers.push_back(handler);

        // 按优先级降序排序处理器
        std::sort(m_handlers.begin(), m_handlers.end(),
                    [](const std::shared_ptr<IRouteHandler> &a, const std::shared_ptr<IRouteHandler> &b)
                    {
                        return a->getPriority() > b->getPriority();
                    });
    }
    return *this;
}

Router &Router::addMiddleware(MiddlewareHandler middleware)
{
    if (middleware)
    {
        m_middlewares.push_back(middleware);
    }
    return *this;
}

RouteGroup &Router::group(const std::string &prefix)
{
    m_groups.emplace_back(prefix);
    return m_groups.back();
}

void Router::handleRequest(Poco::Net::HTTPServerRequest &request,
                            Poco::Net::HTTPServerResponse &response)
{
    // 创建请求上下文
    RequestContext context{request, response, {}};
    try
    {
        // 执行全局中间件
        if (!executeMiddlewareChain(m_middlewares, context))
        {
            return;
        }

        // 查找匹配的路由处理器
        auto handler = findMatchingHandler(context);

        if (handler)
        {
            // 处理请求
            handler->handle(context);
        }
        else if (m_notFoundHandler)
        {
            // 使用404处理器
            m_notFoundHandler->handle(context);
        }
        else
        {
            // 如果没有设置404处理器，返回简单的404响应
            CLink::HttpResponseUtils::sendErrorJson(
                response,
                CLink::HttpResponseUtils::Status::NOT_FOUND,
                "NOT_FOUND",
                "Not Found");
        }
    }
    catch (const Error::CLinkException &error)
    {
        // 处理错误
        if (m_errorHandler)
        {
            std::shared_ptr<ErrorHandler> errorHandler =
                std::dynamic_pointer_cast<ErrorHandler>(m_errorHandler);
            if (errorHandler)
            {
                errorHandler->handleError(context, error);
            }
            else
            {
                // 如果错误处理器不是ErrorHandler类型，使用默认错误响应
                CLink::HttpResponseUtils::sendErrorJson(
                    response,
                    CLink::HttpResponseUtils::Status::INTERNAL_SERVER_ERROR,
                    "INTERNAL_SERVER_ERROR",
                    "Internal Server Error");
            }
        }
        else
        {
            // 如果没有设置错误处理器，返回简单的错误响应
            CLink::HttpResponseUtils::sendErrorJson(
                response,
                CLink::HttpResponseUtils::Status::INTERNAL_SERVER_ERROR,
                "INTERNAL_SERVER_ERROR",
                "Internal Server Error");
        }
    }
    catch (const std::exception &ex)
    {
        // 处理其他异常
        if (m_errorHandler)
        {
            std::shared_ptr<ErrorHandler> errorHandler =
                std::dynamic_pointer_cast<ErrorHandler>(m_errorHandler);
            if (errorHandler)
            {
                CLink::Error::CLinkException error(Error::ErrorCode::INTERNAL_ERROR, ex.what());
                errorHandler->handleError(context, error);
            }
            else
            {
                // 如果错误处理器不是ErrorHandler类型，使用默认错误响应
                CLink::HttpResponseUtils::sendErrorJson(
                    response,
                    CLink::HttpResponseUtils::Status::INTERNAL_SERVER_ERROR,
                    "INTERNAL_SERVER_ERROR",
                    ex.what());
            }
        }
        else
        {
            // 如果没有设置错误处理器，返回简单的错误响应
            CLink::HttpResponseUtils::sendErrorJson(
                response,
                CLink::HttpResponseUtils::Status::INTERNAL_SERVER_ERROR,
                "INTERNAL_SERVER_ERROR",
                ex.what());
        }
    }
}

void Router::setNotFoundHandler(std::shared_ptr<IRouteHandler> handler)
{
    m_notFoundHandler = handler;
}

void Router::setErrorHandler(std::shared_ptr<IRouteHandler> handler)
{
    m_errorHandler = handler;
}

bool Router::executeMiddlewareChain(const std::vector<MiddlewareHandler> &middlewares,
                                    RequestContext &context)
{
    // 执行所有中间件
    for (const auto &middleware : middlewares)
    {
        if (!middleware(context))
        {
            // 如果中间件返回false，停止处理
            return false;
        }
    }
    return true;
}

std::shared_ptr<IRouteHandler> Router::findMatchingHandler(RequestContext &context)
{
    const auto &request = context.request;

    // 首先检查路由组
    for (const auto &group : m_groups)
    {
        // 检查请求路径是否以组前缀开头
        if (request.getURI().find(group.getPrefix()) == 0)
        {
            // 执行组中间件
            if (!executeMiddlewareChain(group.getMiddlewares(), context))
            {
                return nullptr;
            }

            // 查找匹配的处理器
            for (const auto &handler : group.getHandlers())
            {
                if (handler->matches(context))
                {
                    return handler;
                }
            }
        }
    }

    // 然后检查全局处理器
    for (const auto &handler : m_handlers)
    {
        if (handler->matches(context))
        {
            return handler;
        }
    }

    // 没有找到匹配的处理器
    return nullptr;
}

} // namespace Router
} // namespace CLink